package com.health.hfm.sys.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.health.core.constant.RedisConstants;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author tidudada
 * @Description 企业配置信息
 * @Date 下午5:29 2022/1/14
 **/
// 默认的方案或许是最好的最佳保密的
// 我尝试了重写更多的方法使用自己的方式创建数据源成功 但是sqlsesssion却仍是配置的
@Component
@Slf4j
public class HfmEnterpriseConfigService implements DynamicDataSourceProvider {

    private final Logger logger = LoggerFactory.getLogger(HfmEnterpriseConfigService.class);

    public static Map<String, DataSource> dataSourceMap;

    private static final Map<String, EnterpriseEntity> enterpriseEntityMap;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void initialize() {
        enterpriseDatasourceToR();
        logger.info("--- HFM-化完成 ---");
    }

    public void enterpriseDatasourceToR() {
        Set<String> keySet = enterpriseEntityMap.keySet();
        HashMap<String, String> hashMap = new HashMap<>();
        keySet.forEach(s -> {
            hashMap.put(s,JSON.toJSONString(enterpriseEntityMap.get(s)));
        });

        redisTemplate.opsForHash().putAll(RedisConstants.FM_ENTERPRISE_DATASOURCE_ALL, hashMap);
    }

    static {
        Properties properties = new Properties();
        try {
            properties.load(HfmEnterpriseConfigService.class.getClassLoader().getResourceAsStream("config/datasource.properties"));
        } catch (IOException e) {
            log.info("读取配置文件失败，mes{}",e.getMessage());
        }
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUsername(properties.getProperty("username"));
        druidDataSource.setPassword(properties.getProperty("password"));
        druidDataSource.setDriverClassName(DatabaseDriver.MYSQL.getDriverClassName());
        druidDataSource.setUrl(properties.getProperty("url"));
        JdbcTemplate jdbcTemplate = new JdbcTemplate(druidDataSource);
        enterpriseEntityMap = jdbcTemplate.query(properties.getProperty("sql"),
                new Object[]{properties.getProperty("type")}, new BeanPropertyRowMapper<EnterpriseEntity>(EnterpriseEntity.class))
                .stream().collect(Collectors.toMap(EnterpriseEntity::getCompanycode, enterpriseEntity -> enterpriseEntity));
    }

    @Override
    public Map<String, DataSource> loadDataSources() {
        HashMap<String, DataSource> dataSourceHashMap = new HashMap<>();
        Set<String> keySet = enterpriseEntityMap.keySet();
        for (String key : keySet) {
            EnterpriseEntity entity = enterpriseEntityMap.get(key);
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setUrl(append(entity));
            druidDataSource.setDriverClassName(DatabaseDriver.MYSQL.getDriverClassName());
            druidDataSource.setUsername(entity.getDbuser());
            druidDataSource.setPassword(entity.getDbpwd());
            dataSourceHashMap.put(key, druidDataSource);
        }
        dataSourceMap = dataSourceHashMap;
        return dataSourceHashMap;
    }

    public static String append(EnterpriseEntity enterpriseEntity) {
        return "jdbc:mysql://" +
                enterpriseEntity.getDbhost() +
                ":" +
                enterpriseEntity.getDbport() +
                "/" +
                enterpriseEntity.getDbname() +
                "?" +
                "autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
    }

}
